<?php

abstract class Soul_Model_Property_Base extends Soul_Classes_Object{
    
    public function __construct() {
        parent::__construct();
        $this->addData(array(
            'name'=>'',
            'is_primary'=>FALSE,
            'is_increment'=>FALSE,
            'default_value'=>NULL,
            'insertable'=>TRUE,
            'updateable'=>TRUE,
            'required'=>FALSE,
            'length'=>0,
            'label'=>'',
            'description'=>'',
            'input_type'=>'',
            'versionable'=>FALSE,
            'rules'=>array()
        ));
    }

    public function getInsertable() {
        if ($this->getIsIncrement()) {
            return FALSE;
        }
        return $this->data['insertable'];
    }

    public function getUpdateable() {
        if ($this->getIsPrimary()) {
            return FALSE;
        }
        return $this->data['updateable'];
    }

    public function compareValue($source, $value) {
        return $source == $value;
    }

    public function validate($value) {
        if ($this->getRequired() && empty($value)) {
            throw new Soul_Model_Exception('property_error',
                    sprintf('property [%s] is required', $this->getPropertyName()));
        }

        if (!empty($value)) {
            foreach ($this->getRules() as $rule) {
                if (!$rule->check($value)) {
                    throw new Soul_Model_Exception('property_error',
                            sprintf('property [%s] value [%s] valid', $this->getPropertyName(), $value));
                }
            }
        }

        return TRUE;
    }

    public function convertToDb($value) {
        if (is_null($value)) {
            return $this->getDefaultValue();
        }
        if (strlen($value) == 0 && empty($value)) {
            return $this->getDefaultValue();
        }
        return $value;
    }

    public function convertFromDb($value) {
        return $value;
    }

    public function addRule(Soul_Validation_Rule_Base $rule) {
        $rules = $this->getRules();
        $rules[] = $rule;
        $this->setData('rules', $rules);
        return $this;
    }

    public abstract function getPropertyType();

    public abstract function getParameterType();
}